package cn.omisheep.commons.util.web;

import com.fasterxml.jackson.core.JsonProcessingException;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author zhouxinchen[1269670415@qq.com]
 * @since 1.0.4
 */
@SuppressWarnings("all")
public class ConvertUtil {

    private ConvertUtil() {
        throw new UnsupportedOperationException();
    }

    public static Map<String, String> addStringToMap(String keyVals,
                                                     Map<String, String> map) {
        String[] kvs = keyVals.split("&");
        for (String kv : kvs) {
            String[] n     = kv.split("=");
            String   key   = n[0];
            String   value = n[1];
            map.put(key, value);
        }
        return map;
    }

    public static Map<String, String> stringToMap(String keyVals) {
        return addStringToMap(keyVals, new HashMap<>());
    }

    public static String mapToString(Map<String, String> map) {
        if (map == null | map.isEmpty()) return "";
        Iterator<Map.Entry<String, String>> i = map.entrySet().iterator();
        if (!i.hasNext())
            return "";
        StringBuilder sb = new StringBuilder();
        for (; ; ) {
            Map.Entry<String, String> e     = i.next();
            String                    key   = e.getKey();
            String                    value = e.getValue();
            sb.append(key).append('=').append(value);
            if (!i.hasNext())
                return sb.toString();
            sb.append('&');
        }
    }

    public static String mapListToString(Map<String, List<String>> map) {
        Iterator<Map.Entry<String, List<String>>> i = map.entrySet().iterator();
        if (!i.hasNext())
            return "";
        StringBuilder sb = new StringBuilder();
        for (; ; ) {
            Map.Entry<String, List<String>> e     = i.next();
            String                          key   = e.getKey();
            List<String>                    value = e.getValue();
            sb.append(key).append('=');
            if (value != null && value.size() != 0) {
                Iterator<String> i2 = value.iterator();
                for (; ; ) {
                    String next = i2.next();
                    sb.append(next);
                    if (i2.hasNext()) {
                        sb.append(',');
                    } else {
                        break;
                    }
                }
            }
            if (!i.hasNext())
                return sb.toString();
            sb.append('&');
        }
    }

    public static String objectToJSON(Object o) throws JsonProcessingException {
        return JSONUtils.toJSONString(o);
    }

    public static String objectToForm(Object o) {
        if (o == null) {
            return "";
        }
        if (o instanceof Map) {
            return parseParamMap((Map) o);
        }

        return objectToForm(JSONUtils.parseJSON(JSONUtils.toJSONString(o), Map.class));
    }

    public static Map<String, String> objectToMap(Object o) {
        return objectToMap(objectToForm(o), new HashMap<>());
    }

    public static Map<String, String> objectToMap(Object o,
                                                  Map<String, String> map) {
        return addStringToMap(objectToForm(o), map);
    }

    private static String parseParamMap(Map<String, ?> paramMap) {
        if (paramMap == null || paramMap.isEmpty()) return "";
        StringBuilder param = new StringBuilder();

        for (Map.Entry<String, ?> entry : paramMap.entrySet()) {
            param.append(entry.getKey())
                    .append('=')
                    .append(urlEncode(entry.getValue().toString()))
                    .append("&");
        }
        return param.substring(0, param.length() - 1);
    }

    private static String urlEncode(String text) {
        try {
            return URLEncoder.encode(text, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return "";
        }
    }

    private String urlDecode(String text) {
        try {
            return URLDecoder.decode(text, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return "";
        }
    }

}
